﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;

namespace CommServer.Common.Json
{
    public class JsonArray : JsonValue, IList<JsonValue>
    {
        private readonly List<JsonValue> _values = new List<JsonValue>();

        #region 公开属性

        internal override object Value
        {
            get { return _values; }
        }

        public override sealed JsonType JsonType
        {
            get { return JsonType.Array; }
        }

        public bool IsReadOnly
        {
            get { return false; }
        }

        public override int Count
        {
            get { return _values.Count; }
        }

        public override JsonValue this[int index]
        {
            get { return _values[index]; }
            set { _values[index] = value; }
        }

        #endregion

        #region 构造函数

        public JsonArray(IEnumerable<JsonValue> items)
        {
            CheckNull(items, "items");
            _values.AddRange(items);
        }

        internal JsonArray(IList items)
        {
            CheckNull(items, "items");
            IEnumerator enumerator = items.GetEnumerator();
            while (enumerator.MoveNext())
            {
                _values.Add(Convert(enumerator.Current));
            }
        }

        public JsonArray(params JsonValue[] items)
        {
            if (items != null)
            {
                _values.AddRange(items);
            }
        }

        #endregion

        #region 接口方法

        /// <summary>
        ///     搜索指定的对象，并返回整个 JsonArray 中第一个匹配项的从零开始的索引。
        /// </summary>
        /// <param name="item">要在JsonArray 中查找的对象。对于引用类型，该值可以为 null</param>
        /// <returns> 如果在整个 JsonArray 中找到 item 的第一个匹配项，则为该项的从零开始的索引；否则为</returns>
        public int IndexOf(JsonValue item)
        {
            return _values.IndexOf(item);
        }

        /// <summary>
        ///     将元素插入 JsonArray 的指定索引处。
        /// </summary>
        /// <param name="index">从零开始的索引，应在该位置插入 item。</param>
        /// <param name="item">要插入的对象。对于引用类型，该值可以为 null。</param>
        public void Insert(int index, JsonValue item)
        {
            if (index < 0)
            {
                throw new ArgumentOutOfRangeException("index");
            }
            _values.Insert(index, item);
        }

        /// <summary>
        ///     移除 JsonArray 的指定索引处的元素。
        /// </summary>
        /// <param name="index">要移除的元素的从零开始的索引。</param>
        public void RemoveAt(int index)
        {
            if (index < 0 || index >= _values.Count)
            {
                throw new ArgumentOutOfRangeException("index");
            }
            _values.RemoveAt(index);
        }

        /// <summary>
        ///     将对象添加到 JsonArray 的结尾处。
        /// </summary>
        /// <param name="item"></param>
        public void Add(JsonValue item)
        {
            _values.Add(item);
        }

        /// <summary>
        ///     从 JsonArray 中移除所有元素。
        /// </summary>
        public void Clear()
        {
            _values.Clear();
        }

        /// <summary>
        ///     确定某元素是否在 JsonArray 中。
        /// </summary>
        /// <param name="item">要在 JsonArray 中查找的对象。对于引用类型，该值可以为 null。</param>
        /// <returns>如果在 JsonArray 中找到 item，则为 true，否则为 false。</returns>
        public bool Contains(JsonValue item)
        {
            return _values.Contains(item);
        }

        /// <summary>
        ///     将整个 JsonArray 复制到兼容的一维数组中，从目标数组的指定索引位置开始放置。
        /// </summary>
        /// <param name="array">作为从 JsonArray 复制的元素的目标位置的一维 System.Array。System.Array 必须具有从零开始的索引。</param>
        /// <param name="arrayIndex">array 中从零开始的索引，将在此处开始复制。</param>
        public void CopyTo(JsonValue[] array, int arrayIndex)
        {
            CheckNull(array, "array");
            _values.CopyTo(array, arrayIndex);
        }

        /// <summary>
        ///     从 JsonArray 中移除特定对象的第一个匹配项。
        /// </summary>
        /// <param name="item">要从 JsonArray 中移除的对象。对于引用类型，该值可以为 null。</param>
        /// <returns>如果成功移除 item，则为 true；否则为 false。如果在 JsonArray 中没有找到item，该方法也会返回 false。</returns>
        public bool Remove(JsonValue item)
        {
            return _values.Remove(item);
        }

        /// <summary>
        ///     返回循环访问 JsonArray 的枚举器。
        /// </summary>
        /// <returns>用于 JsonArray 的 Enumerator</returns>
        IEnumerator<JsonValue> IEnumerable<JsonValue>.GetEnumerator()
        {
            return _values.GetEnumerator();
        }

        /// <summary>
        ///     返回循环访问 JsonArray 的枚举器。
        /// </summary>
        /// <returns>用于 JsonArray 的 Enumerator</returns>
        IEnumerator IEnumerable.GetEnumerator()
        {
            return _values.GetEnumerator();
        }

        /// <summary>
        ///     将指定集合的元素添加到 JsonArray 的末尾。
        /// </summary>
        /// <param name="items">一个集合，其元素应被添加到 JsonArray 的末尾。集合自身不能为 null，但它可以包含为 null 的元素。</param>
        public void AddRange(IEnumerable<JsonValue> items)
        {
            CheckNull(items, "items");
            _values.AddRange(items);
        }

        /// <summary>
        ///     将指定集合的元素添加到 JsonArray 的末尾。
        /// </summary>
        /// <param name="items"></param>
        public void AddRange(params JsonValue[] items)
        {
            if (items != null)
            {
                _values.AddRange(items);
            }
        }

        #endregion

        /// <summary>
        ///     在StringBuilder中构建该对象的Json格式字符串输出
        /// </summary>
        /// <param name="builder">操作的StringBuilder对象</param>
        internal override void Builder(StringBuilder builder)
        {
            CheckNull(builder, "builder");
            builder.Append('[');
            for (int i = 0; i < _values.Count; i++)
            {
                if (i != 0)
                {
                    builder.Append(',');
                }
                JsonValue jsonValue = _values[i];
                if (jsonValue == null)
                {
                    builder.Append("null");
                }
                else
                {
                    jsonValue.Builder(builder);
                }
            }
            builder.Append(']');
        }

        /// <summary>
        ///     将JSON的字符串表示形式转换为Json对象。
        /// </summary>
        /// <param name="s">包含要转换的Json字符串</param>
        /// <returns>一个Json对象</returns>
        public new static JsonArray Parse(string s)
        {
            return (JsonArray)JsonValue.Parse(s);
        }

        /// <summary>
        ///     将JSON的字符串表示形式转换为Json对象。一个指示转换是否成功的返回值。
        /// </summary>
        /// <param name="s">包含要转换的Json字符串</param>
        /// <param name="value">当此方法返回时，如果转换成功，则包含一个Json对象；如果转换失败，则包含 null。</param>
        /// <returns>如果 s 转换成功，则为 true；否则为 false。</returns>
        public static bool TryParse(string s, out JsonArray value)
        {
            if (String.IsNullOrWhiteSpace(s))
            {
                value = null;
                return false;
            }
            JsonValue result;
            //解析JSON字符串
            var parser = new JsonReader(s);
            parser.TryParser(out result);
            value = result as JsonArray;
            return value != null;
        }
    }
}
